#include "adc_keyboard.h"
#include "polsys.h"

// #define _KEY_ADV_STEP       ((_KEYBOARD_MAX_VALUE - _KEYBOARD_MIN_VALUE) / _KEYBOARD_NUM)
// #define _KEY_ADV_HALF_STEP  (_KEY_ADV_STEP / 2)
// #define _KEY0_ADV_L         (_KEYBOARD_MAX_VALUE - _KEY_ADV_HALF_STEP)



static keyboard_t mKB;
#if (_KEYBOARD_RUN_MODE == 1) && (_KEYBOARD_ASYNC_NOTIFY == 1)
static volatile bool mNeedNotify = false;
#endif
#if (_KEYBOARD_RUN_MODE == 0) || (_KEYBOARD_ASYNC_NOTIFY == 1)
static polsys_task_t mAdcKeyboardTask;
#endif


static key_num_t GetPressedKey(u16 adv);
static void Updata();
static void AdcKeyboardLoop();


IN_LINE void Keyboard_Init()
{
    memset(&mKB, 0, sizeof(keyboard_t));
#if (_KEYBOARD_RUN_MODE == 0)
    Polsys_TaskInit(&mAdcKeyboardTask, AdcKeyboardLoop, _KEYBOARD_SCAN_INTERVAL);
#elif (_KEYBOARD_ASYNC_NOTIFY == 1)
    Polsys_TaskInit(&mAdcKeyboardTask, AdcKeyboardLoop, 10);
#endif
}

IN_LINE key_value_t Keyboard_GetLastKey()
{
#ifdef _KEYBOARD_CONVERT_KEY_VALUE
    #error "not support yet."
#else
    return mKB.LastKey;
#endif
}

IN_LINE key_status_t Keyboard_GetLastStatus()
{
    return mKB.LastStatus;
}

// IN_LINE key_buff_t * Keyboard_GetBuff()
// {
//     return &mKB.KeyBuff;
// }

void Keyboard_SetEventCb(void (*EventCb)(const keyboard_t * Sender))
{
    mKB.EventCb = EventCb;
}

#if (_KEYBOARD_RUN_MODE == 1)
IN_LINE void KeyBoard_EvNewAdv(u16 adv)
{
    mKB.Adv = adv;
    Updata();
}
#endif


// 内部函数

typedef struct _key_value_range_t
{
    u16 h;
    u16 l;
}key_value_range_t;

static const key_value_range_t mKeyVR[_KEYBOARD_NUM] = {
    {_KEYBOARD_KEY0_V_H, _KEYBOARD_KEY0_V_L},
    {_KEYBOARD_KEY1_V_H, _KEYBOARD_KEY1_V_L},
    {_KEYBOARD_KEY2_V_H, _KEYBOARD_KEY2_V_L},
    {_KEYBOARD_KEY3_V_H, _KEYBOARD_KEY3_V_L},
    {_KEYBOARD_KEY4_V_H, _KEYBOARD_KEY4_V_L},
    {_KEYBOARD_KEY5_V_H, _KEYBOARD_KEY5_V_L},
    };

// 解析AD值，返回哪个按钮按下，0XFF表示无任何按钮按下
static key_num_t GetPressedKey(u16 adv)
{
    key_num_t i;
    for(i=0; i<_KEYBOARD_NUM; i++)
    {
        if(adv <= mKeyVR[i].h && adv >= mKeyVR[i].l)return i;
    }
    // if(i == 6)  // 没有任何键按下
    return 0XFF;
}

static void Updata()
{
    key_num_t pressed_key;

    pressed_key = GetPressedKey(mKB.Adv);
#if _KEYBOARD_FILTER_MODE == 1
    if(mKB.PressedKey == pressed_key)   // 连续2次同一个键按下
    {
#endif
        if(pressed_key < 0xff)   // 有键按下
        {
            if(mKB.LastKey == pressed_key)    // 上次操作的是这个键
            {
                if(mKB.LastStatus == KEY_STATUS_RELEASE)
                {
                    mKB.LastStatus = KEY_STATUS_PRESS;
#if (_KEYBOARD_ASYNC_NOTIFY == 0)
                    if(mKB.EventCb)mKB.EventCb(&mKB);   // 通知有按键按下
#else
                    mNeedNotify = true;                 // 通知有按键按下
#endif
                }
            }
            else    // 上次操作的不是这个键，现在有新的按键按下，如果上次是按下，要通知上次的按键松手，再通知新的按键按下
            {
#if (_KEYBOARD_ASYNC_NOTIFY == 0)
                if(mKB.LastStatus == KEY_STATUS_PRESS)
                {
                    mKB.LastStatus = KEY_STATUS_RELEASE;
                    if(mKB.EventCb)mKB.EventCb(&mKB);   
                }
#endif
                mKB.LastKey = pressed_key;
                mKB.LastStatus = KEY_STATUS_PRESS;
#if (_KEYBOARD_ASYNC_NOTIFY == 0)
                    if(mKB.EventCb)mKB.EventCb(&mKB);
#else
                mNeedNotify = true;                     // 通知新的按键按下
#endif
            }
        }
        else    // 没有按键按下
        {
            if(mKB.LastStatus == KEY_STATUS_PRESS)
            {
                mKB.LastStatus = KEY_STATUS_RELEASE;
#if (_KEYBOARD_ASYNC_NOTIFY == 0)
                if(mKB.EventCb)mKB.EventCb(&mKB);
#else
                mNeedNotify = true;   // 通知上次按键松手
#endif
            }
        }
#if _KEYBOARD_FILTER_MODE == 1
    }
    else
    {
        mKB.PressedKey = pressed_key;
    }
#endif
}

// 10ms执行一次
static void AdcKeyboardLoop()
{
#if (_KEYBOARD_RUN_MODE == 0)
    mKB.Adv = _Keyboard_GetValue();
    Updata();
#endif
#if (_KEYBOARD_ASYNC_NOTIFY == 1)
    if(mNeedNotify)
    {
        mNeedNotify = false;
        if(mKB.EventCb)mKB.EventCb(&mKB);
    }
#endif
}





